{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">  原文地址 https://mp.weixin.qq.com/s?__biz=MzIzNzA4NDk3Nw==&mid=2457739380&idx=1&sn=122f15af3520857314199127ca79cad4&chksm=ff44882ac833013cb52d848aa03f2547f973d05572a0e90f3f68e662f573076507853691e222&mpshare=1&scene=24&srcid=&sharer_sharetime=1590505368566&sharer_shareid=316859bf78c7a4dcfe65351f82355327&key=4a6324d6ed20374b2ee3f6b714ba4c639a666cd163fba9d5e94aa754ed867c7dc268b148c37973ba3f2d81307162049ef360b855e17126c1be1067fa76d178362807a2501f080fdf9b34e15cbe16781d&ascene=14&uin=MTk3NzE3NDc2Nw%3D%3D&devicetype=Windows+10+x64&version=62090070&lang=zh_CN&exportkey=AQcehB42P8T%2BSFIJUqHMMDM%3D&pass_ticket=Acu03Vea4OzkX5rFiRthgfsryW17Dq7NNIVczerRUrlcb0m3B1ufUlsIrQ3a9OKy\n",
    "\n",
    "\n",
    "本文于网络整理，版权归原作者所有，如来源信息有误或侵犯权益，请联系我删除。\n",
    "\n",
    "自己写 Python 也有四五年了，一直是用自己的 “强迫症” 在维持自己代码的质量。都有去看 Google 的 Python 代码规范，对这几年的工作经验，做个简单的笔记，如果你也在学 Python，准备要学习 Python，希望这篇文章对你有用。  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 首先\n",
    "\n",
    "- 建议 1、理解 Pythonic 概念—- 详见 Python 中的《Python 之禅》\n",
    "\n",
    "- 建议 2、编写 Pythonic 代码\n",
    "\n",
    "    （1）避免不规范代码，比如只用大小写区分变量、使用容易混淆的变量名、害怕过长变量名等。有时候长的变量名会使代码更加具有可读性。\n",
    "\n",
    "    （2）深入学习 Python 相关知识，比如语言特性、库特性等，比如 Python 演变过程等。深入学习一两个业内公认的 Pythonic 的代码库，比如 Flask 等。\n",
    "\n",
    "- 建议 3：理解 Python 与 C 的不同之处，比如缩进与 {}，单引号双引号，三元操作符？， Switch-Case 语句等。\n",
    "\n",
    "- 建议 4：在代码中适当添加注释\n",
    "\n",
    "- 建议 5：适当添加空行使代码布局更加合理\n",
    "\n",
    "- 建议 6：编写函数的 4 个原则\n",
    "\n",
    "    （1）函数设计要尽量短小，嵌套层次不宜过深\n",
    "\n",
    "    （2）函数声明应该做到合理、简单、易用\n",
    "\n",
    "    （3）函数参数设计应该考虑向下兼容\n",
    "\n",
    "    （4）一个函数只做一件事，尽量保证函数粒度的一致性\n",
    "\n",
    "- 建议 7：将常量集中在一个文件，且常量名尽量使用全大写字母"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. 编程惯用法\n",
    "\n",
    "- 建议 8：利用 assert 语句来发现问题，但要注意，断言 assert 会影响效率\n",
    "\n",
    "- 建议 9：数据交换值时不推荐使用临时变量，而是直接 a, b = b, a\n",
    "\n",
    "- 建议 10：充分利用惰性计算（Lazy evaluation）的特性，从而避免不必要的计算\n",
    "\n",
    "- 建议 11：理解枚举替代实现的缺陷（最新版 Python 中已经加入了枚举特性）\n",
    "\n",
    "- 建议 12：不推荐使用 type 来进行类型检查，因为有些时候 type 的结果并不一定可靠。如果有需求，建议使用 isinstance 函数来代替\n",
    "\n",
    "- 建议 13：尽量将变量转化为浮点类型后再做除法（Python3 以后不用考虑）\n",
    "\n",
    "- 建议 14：警惕 eval() 函数的安全漏洞，有点类似于 SQL 注入\n",
    "\n",
    "- 建议 15：使用 enumerate() 同时获取序列迭代的索引和值\n",
    "\n",
    "- 建议 16：分清 == 和 is 的适用场景，特别是在比较字符串等不可变类型变量时（详见评论）\n",
    "\n",
    "- 建议 17：尽量使用 Unicode。在 Python2 中编码是很让人头痛的一件事，但 Python3 就不用过多考虑了\n",
    "\n",
    "- 建议 18：构建合理的包层次来管理 Module"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 基础用法\n",
    "\n",
    "- 建议 19：有节制的使用 from…import 语句，防止污染命名空间\n",
    "\n",
    "- 建议 20：优先使用 absolute import 来导入模块（Python3 中已经移除了 relative import）\n",
    "\n",
    "- 建议 21：i+=1 不等于 ++i，在 Python 中，++i 前边的加号仅表示正，不表示操作\n",
    "\n",
    "- 建议 22：习惯使用 with 自动关闭资源，特别是在文件读写中\n",
    "\n",
    "- 建议 23：使用 else 子句简化循环（异常处理）\n",
    "\n",
    "- 建议 24：遵循异常处理的几点基本原则\n",
    "\n",
    "    （1）注意异常的粒度，try 块中尽量少写代码\n",
    "\n",
    "    （2）谨慎使用单独的 except 语句，或 except Exception 语句，而是定位到具体异常\n",
    "\n",
    "    （3）注意异常捕获的顺序，在合适的层次处理异常\n",
    "\n",
    "    （4）使用更加友好的异常信息，遵守异常参数的规范\n",
    "\n",
    "- 建议 25：避免 finally 中可能发生的陷阱\n",
    "\n",
    "- 建议 26：深入理解 None，正确判断对象是否为空。\n",
    "\n",
    "- 建议 27：连接字符串应优先使用 join 函数，而不是 + 操作\n",
    "\n",
    "- 建议 28：格式化字符串时尽量使用 format 函数，而不是 % 形式\n",
    "\n",
    "- 建议 29：区别对待可变对象和不可变对象，特别是作为函数参数时\n",
    "\n",
    "- 建议 30：[], {} 和 ()：一致的容器初始化形式。使用列表解析可以使代码更清晰，同时效率更高\n",
    "\n",
    "- 建议 31：函数传参数，既不是传值也不是传引用，而是传对象或者说对象的引用\n",
    "\n",
    "- 建议 32：警惕默认参数潜在的问题，特别是当默认参数为可变对象时\n",
    "\n",
    "- 建议 33：函数中慎用变长参数 **args 和** **kargs**\n",
    "\n",
    "    （1）这种使用太灵活，从而使得函数签名不够清晰，可读性较差\n",
    "\n",
    "    （2）如果因为函数参数过多而是用变长参数简化函数定义，那么一般该函数可以重构\n",
    "\n",
    "- 建议 34：深入理解 str() 和 repr() 的区别\n",
    "\n",
    "    （1）两者之间的目标不同：str 主要面向客户，其目的是可读性，返回形式为用户友好性和可读性都比较高的字符串形式；而 repr 是面向 Python 解释器或者说 Python 开发人员，其目的是准确性，其返回值表示 Python 解释器内部的定义\n",
    "\n",
    "    （2）在解释器中直接输入变量，默认调用 repr 函数，而 print(var) 默认调用 str 函数\n",
    "\n",
    "    （3）repr 函数的返回值一般可以用 eval 函数来还原对象\n",
    "\n",
    "    （4）两者分别调用对象的内建函数 **__str__** () 和 **__repr__** ()\n",
    "\n",
    "- 建议 35：分清静态方法 staticmethod 和类方法 classmethod 的使用场景"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. 库的使用\n",
    "\n",
    "- 建议 36：掌握字符串的基本用法\n",
    "\n",
    "- 建议 37：按需选择 sort() 和 sorted() 函数\n",
    "\n",
    "sort() 是列表在就地进行排序，所以不能排序元组等不可变类型。\n",
    "\n",
    "sorted() 可以排序任意的可迭代类型，同时不改变原变量本身。\n",
    "\n",
    "- 建议 38：使用 copy 模块深拷贝对象，区分浅拷贝（shallow copy）和深拷贝（deep copy）\n",
    "\n",
    "- 建议 39：使用 Counter 进行计数统计，Counter 是字典类的子类，在 collections 模块中\n",
    "\n",
    "- 建议 40：深入掌握 ConfigParse\n",
    "\n",
    "- 建议 41：使用 argparse 模块处理命令行参数\n",
    "\n",
    "- 建议 42：使用 pandas 处理大型 CSV 文件\n",
    "\n",
    "Python 本身提供一个 CSV 文件处理模块，并提供 reader、writer 等函数。\n",
    "\n",
    "Pandas 可提供分块、合并处理等，适用于数据量大的情况，且对二维数据操作更方便。\n",
    "\n",
    "- 建议 43：使用 ElementTree 解析 XML\n",
    "\n",
    "- 建议 44：理解模块 pickle 的优劣\n",
    "\n",
    "优势：接口简单、各平台通用、支持的数据类型广泛、扩展性强\n",
    "\n",
    "劣势：不保证数据操作的原子性、存在安全问题、不同语言之间不兼容\n",
    "\n",
    "- 建议 45：序列化的另一个选择 JSON 模块：load 和 dump 操作\n",
    "\n",
    "- 建议 46：使用 traceback 获取栈信息\n",
    "\n",
    "- 建议 47：使用 logging 记录日志信息\n",
    "\n",
    "- 建议 48：使用 threading 模块编写多线程程序\n",
    "\n",
    "- 建议 49：使用 Queue 模块使多线程编程更安全"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. 设计模式\n",
    "\n",
    "- 建议 50：利用模块实现单例模式\n",
    "\n",
    "- 建议 51：用 mixin 模式让程序更加灵活\n",
    "\n",
    "- 建议 52：用发布 - 订阅模式实现松耦合\n",
    "\n",
    "- 建议 53：用状态模式美化代码"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. 内部机制\n",
    "\n",
    "- 建议 54：理解 build-in 对象\n",
    "\n",
    "- 建议 55：**__init__** () 不是构造方法，理解 **__new__** () 与它之间的区别\n",
    "\n",
    "- 建议 56：理解变量的查找机制，即作用域\n",
    "\n",
    "    - 局部作用域\n",
    "\n",
    "    - 全局作用域\n",
    "\n",
    "    - 嵌套作用域\n",
    "    - \n",
    "    - 内置作用域\n",
    "\n",
    "- 建议 57：为什么需要 self 参数\n",
    "\n",
    "- 建议 58：理解 MRO（方法解析顺序）与多继承\n",
    "\n",
    "- 建议 59：理解描述符机制\n",
    "\n",
    "- 建议 60：区别 **__getattr__** () 与 **__getattribute__** () 方法之间的区别\n",
    "\n",
    "- 建议 61：使用更安全的 property\n",
    "\n",
    "- 建议 62：掌握元类 metaclass\n",
    "\n",
    "- 建议 63：熟悉 Python 对象协议\n",
    "\n",
    "- 建议 64：利用操作符重载实现中缀语法\n",
    "\n",
    "- 建议 65：熟悉 Python 的迭代器协议\n",
    "\n",
    "- 建议 66：熟悉 Python 的生成器\n",
    "\n",
    "- 建议 67：基于生成器的协程和 greenlet，理解协程、多线程、多进程之间的区别\n",
    "\n",
    "- 建议 68：理解 GIL 的局限性\n",
    "\n",
    "- 建议 69：对象的管理和垃圾回收"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7.使用工具辅助项目开发\n",
    "\n",
    "- 建议 70：从 PyPI 安装第三方包\n",
    "\n",
    "- 建议 71：使用 pip 和 yolk 安装、管理包\n",
    "\n",
    "- 建议 72：做 paster 创建包\n",
    "\n",
    "- 建议 73：理解单元测试的概念\n",
    "\n",
    "- 建议 74：为包编写单元测试\n",
    "\n",
    "- 建议 75：利用测试驱动开发（TDD）提高代码的可测性\n",
    "\n",
    "- 建议 76：使用 Pylint 检查代码风格\n",
    "\n",
    "    - 代码风格审查\n",
    "\n",
    "    - 代码错误检查\n",
    "\n",
    "    - 发现重复以及不合理的代码，方便重构\n",
    "\n",
    "    - 高度的可配置化和可定制化\n",
    "\n",
    "    - 支持各种 IDE 和编辑器的集成\n",
    "\n",
    "    - 能够基于 Python 代码生成 UML 图\n",
    "\n",
    "    - 能够与 Jenkins 等持续集成工具相结合，支持自动代码审查\n",
    "\n",
    "- 建议 77：进行高效的代码审查\n",
    "\n",
    "- 建议 78：将包发布到 PyPI"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8. 性能剖析与优化\n",
    "\n",
    "- 建议 79：了解代码优化的基本原则\n",
    "\n",
    "- 建议 80：借助性能优化工具\n",
    "\n",
    "- 建议 81：利用 cProfile 定位性能瓶颈\n",
    "\n",
    "- 建议 82：使用 memory_profiler 和 objgraph 剖析内存使用\n",
    "\n",
    "- 建议 83：努力降低算法复杂度\n",
    "\n",
    "- 建议 84：掌握循环优化的基本技巧\n",
    "\n",
    "    - 减少循环内部的计算\n",
    "\n",
    "    - 将显式循环改为隐式循环，当然这会牺牲代码的可读性\n",
    "\n",
    "    - 在循环中尽量引用局部变量\n",
    "\n",
    "    - 关注内层嵌套循环\n",
    "\n",
    "- 建议 85：使用生成器提高效率\n",
    "\n",
    "- 建议 86：使用不同的数据结构优化性能\n",
    "\n",
    "- 建议 87：充分利用 set 的优势\n",
    "\n",
    "- 建议 88：使用 multiprocessing 模块克服 GIL 缺陷\n",
    "\n",
    "- 建议 89：使用线程池提高效率\n",
    "\n",
    "- 建议 90：使用 Cython 编写扩展模块"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
